/**
 * Copyright (c) 2016-2019 九点科技 All rights reserved.
 *
 * http://www.9dyun.cn
 *
 * 版权所有，侵权必究！
 */
package com.dian.modules.inv.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import com.dian.common.utils.*;
import com.dian.common.validator.ValidatorUtils;
import com.dian.common.validator.group.AddGroup;
import com.dian.common.validator.group.UpdateGroup;
import com.dian.modules.enums.inv.OutHead_OutStateEnum;
import com.dian.modules.enums.inv.OutHead_OutTypeEnum;
import com.dian.modules.inv.entity.TranHeadEntity;
import com.dian.modules.inv.entity.TranLineEntity;
import com.dian.modules.inv.poi.vo.OutHeadExportVO;
import com.dian.modules.inv.poi.vo.OutLineExportVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dian.common.exception.RRException;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.apache.commons.collections.CollectionUtils;
import com.dian.common.server.CommonService;
import com.dian.modules.inv.dao.OutHeadDao;
import com.dian.modules.inv.entity.OutHeadEntity;
import com.dian.modules.inv.service.OutHeadService;
import com.dian.modules.inv.service.OutLineService;
import com.dian.modules.inv.entity.OutLineEntity;
import com.dian.modules.inv.service.OutLineService;

/**
 * 出库单服务实现类
 *
 * @author xiaolai
 * @email xiaolai@9dyun.cn
 * @date 2019-06-11 00:16:18
 */
@Service("outHeadService")
public class OutHeadServiceImpl extends ServiceImpl<OutHeadDao, OutHeadEntity> implements OutHeadService {

    @Autowired
    public CommonService commonService;

    @Autowired
    public OutLineService outLineService;

    /**
     * 出库单分页
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        IPage<OutHeadEntity> page = this.page(new Query<OutHeadEntity>().getPage(params),getQueryWrapper(params) );
        return new PageUtils(page);
    }

    /**
    *  出库单新增
    * @param outHeadEntity
    * @return
    */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean saveInfo(OutHeadEntity outHeadEntity) {
        //设置月份
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        String outMonth = format.format(new Date());
        outHeadEntity.setOutMonth(outMonth);
        //设置出库单编码
        outHeadEntity.setOutNo(commonService.getCode(OutHeadEntity.class));
        //设置出库日期
        outHeadEntity.setOutDate(new DateTime());
        //数据完整性校验
        this.paramsCheck(outHeadEntity,AddGroup.class);
        //设置编码，基础默然初始化数据设置
        //outHeadEntity.setOrderNo(commonService.getOrderCode("XSD"));
        //outHeadEntity.setOrderDate(new Date());
        //保存主表
        this.save(outHeadEntity);
        //保存从表
        if (CollectionUtils.isNotEmpty(outHeadEntity.getOutLineEntityList())) {
            List<OutLineEntity> detailList = outHeadEntity.getOutLineEntityList();
            for (OutLineEntity detail : detailList) {
                detail.setOutId(outHeadEntity.getId());
            }
            outLineService.saveBatch(outHeadEntity.getOutLineEntityList());
        }
        return true;
    }

    /**
     *出库单更新
     * @param outHeadEntity
     * @return
     */
    @Override
    public boolean updateInfo(OutHeadEntity outHeadEntity) {

        //修改状态校验
        this.updateCheck(outHeadEntity.getId());

        //主表数据完整性校验
        this.paramsCheck(outHeadEntity, UpdateGroup.class);
        //更新主表
        this.updateById(outHeadEntity);

        //更新从表
        outLineService.updateInfo(outHeadEntity);


        return true;
    }

    /**
     *出库单删除
     * @param id
     * @return
     */
    @Override
    public boolean deleteInfo(Long id) {

        //删除状态校验
        this.deleteCheck(id);

        //更新从表
        outLineService.deleteInfo(id);

        //更新主表
        this.remove(new QueryWrapper<OutHeadEntity>().eq("id",id));

        return true;
    }

    /**
     * 出库单详情
     * @param id
     * @return
     */
    @Override
    public OutHeadEntity getInfo(Long id) {
        OutHeadEntity outHeadEntity =getById(id);
        List<OutLineEntity> lineList=outLineService.queryList(id);
        outHeadEntity.setOutLineEntityList(lineList);
        return outHeadEntity;
    }

    /**
     * 出库单审核
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean checkInfo(Long id) {
        OutHeadEntity outHeadEntity =this.getById(id);
        //校验状态
        checkCheck(outHeadEntity);
        //状态
        outHeadEntity.setOutState(OutHead_OutStateEnum.AUDITED.getValue());
        outHeadEntity.setCheckDate(new Date());
        outHeadEntity.setCheckUserId(commonService.getUserId());
        outHeadEntity.setCheckUserName(commonService.getUserName());
        return this.updateById(outHeadEntity);
    }

    /**
     * 调拨单审核生成出库单
     * @param outHeadEntity
     * @return
     */
    @Override
    public boolean createOutHead(OutHeadEntity outHeadEntity){
        //校验数据完整性
       this.paramsCheck(outHeadEntity,AddGroup.class);
       //保存主表数据
        this.save(outHeadEntity);
        //判断明细数据是否为空
        if (CollectionUtils.isNotEmpty(outHeadEntity.getOutLineEntityList())) {
            //获取明细数据
            List<OutLineEntity> outLineEntityList = outHeadEntity.getOutLineEntityList();
            //遍历明细数据
            for (OutLineEntity outLineEntity: outLineEntityList) {
                //明细添加主表ID
                outLineEntity.setOutId(outHeadEntity.getId());
            }
            //保存明细数据
            outLineService.saveBatch(outLineEntityList);
        }
        return true;
    }

    /**
         * 出库单导出
         * @param params
         * @return
         */
        public  List<OutHeadExportVO> exportList(Map<String, Object> params){
            List<OutHeadEntity> list = new ArrayList<>();
            if (StrUtil.isBlankIfStr(params.get("exprotType"))) {
                list = this.page(new Query<OutHeadEntity>().getPage(params),getQueryWrapper(params)).getRecords();
            } else {
                list = this.list(getQueryWrapper(params));

            }
            List<OutHeadExportVO> resultList = BeanConverter.convertList(list, OutHeadExportVO.class);
            if(CollectionUtils.isNotEmpty(resultList)){
                for (OutHeadExportVO outHeadExportVO :resultList) {
                    List<OutLineEntity> outLineEntities = outLineService.queryList(outHeadExportVO.getId());
                    outHeadExportVO.setOutLineExportVOList(BeanConverter.convertList(outLineEntities, OutLineExportVO.class));
                }
            }
            return resultList;
    }




    /***********************************************************************************************/
    /****************************************** 私有方法 ********************************************/
    /***********************************************************************************************/

    /**
     * 修改状态校验
     *
     * @param
     */
    private void updateCheck(Long id) {
        OutHeadEntity outHeadEntity =this.getById(id);
        if(outHeadEntity.getOutState().equals(OutHead_OutStateEnum.AUDITED.getValue())){
            throw new RRException(String.format("[%s]些订单已审核，禁止修改"));
        }
        //if(outHeadEntity.getOrderState().equals(OrderHead_OrderStateEnum.AUDITED.getValue())){
        //    throw new RRException(String.format("已审核的销售订单禁止修改"));
        //}
    }
    /**
     * 审核状态校验
     *
     * @param
     */
    private void checkCheck(OutHeadEntity outHeadEntity) {
        if (outHeadEntity.getOutState().equals(OutHead_OutStateEnum.AUDITED.getValue())) {
            throw new RRException(String.format("[%s]些出库单已审核",outHeadEntity.getOutNo()));
        }
        if (outHeadEntity.getOutState().equals(OutHead_OutStateEnum.INVALID.getValue())) {
            throw new RRException(String.format("[%s]些出库单已作废",outHeadEntity.getOutNo()));
        }
    }

    /**
     * 删除状态校验
     *
     * @param
     */
    private void deleteCheck(Long id) {
        OutHeadEntity outHeadEntity =this.getById(id);
        if(!outHeadEntity.getOutState().equals(OutHead_OutStateEnum.WAITCHECK.getValue())){
            throw new RRException(String.format("只允许删除未审核的出库单"));
        }

    }

    /**
     * 新增和修改参数校验
     *
     * @param record
     */
    private void paramsCheck(OutHeadEntity record, Class<?> cls) {

        ValidatorUtils.validateEntity(record, cls);

        if (CollectionUtils.isEmpty(record.getOutLineEntityList())) {
            throw new RRException("出库单明细数据不能为空");
        }
        ListUtils.setPropertyValue(record.getOutLineEntityList(),"warehouseId",record.getWarehouseId());
        ListUtils.setPropertyValue(record.getOutLineEntityList(),"warehouseCode",record.getWarehouseCode());
        ListUtils.setPropertyValue(record.getOutLineEntityList(),"warehouseName",record.getWarehouseName());
        ListUtils.setPropertyValue(record.getOutLineEntityList(),"outMonth",record.getOutMonth());
        ListUtils.setPropertyValue(record.getOutLineEntityList(),"outState",record.getOutState());
       /* ListUtils.setPropertyValue(record.getInLineEntityList(),"warehouseId",record.getWarehouseId());
        ListUtils.setPropertyValue(record.getInLineEntityList(),"warehouseCode",record.getWarehouseCode());
        ListUtils.setPropertyValue(record.getInLineEntityList(),"warehouseName",record.getWarehouseName());
        ListUtils.setPropertyValue(record.getInLineEntityList(),"inMonth",record.getInMonth());
        ListUtils.setPropertyValue(record.getInLineEntityList(),"inState",record.getInState());*/
        for (OutLineEntity outLineEntity : record.getOutLineEntityList()) {
            int index = record.getOutLineEntityList().indexOf(outLineEntity) + 1;

            if (outLineEntity.getQtyNum() == null){
                throw new RRException(String.format("参数错误，出库明细第%s行中[库存数量]不能为空",index));
            }
            if (outLineEntity.getAuxNum() == null ){
                throw new RRException(String.format("参数错误，出库明细第%s行中[辅助数量]不能为空",index));
            }
        }
    }

    /**
     * 获取查询条件
     *
     * @param
     */
    private QueryWrapper<OutHeadEntity> getQueryWrapper(Map<String, Object> params) {
        QueryWrapper<OutHeadEntity> queryWrapper=new QueryWrapper<>();

        if(!StrUtil.isBlankIfStr(params.get("outDate"))){
            String outDate=String.valueOf(params.get("outDate"));
            String[] outDateRange=outDate.split("至");
            if(outDateRange.length==2){
                queryWrapper.gt("out_date", DateUtils.getBeginTimeOfDate(outDateRange[0]));
                queryWrapper.lt("out_date",DateUtils.getBeginTimeOfDate(outDateRange[1]));
            }else{
                queryWrapper.gt("out_date",DateUtils.getBeginTimeOfDate(outDate));
            }
        }
        if(!StrUtil.isBlankIfStr(params.get("outNo"))){
            queryWrapper.like("out_no",params.get("outNo"));
        }
       /* if(!StrUtil.isBlankIfStr(params.get("storeName"))){
            queryWrapper.like("store_name",params.get("storeName"));
        }
        if(!StrUtil.isBlankIfStr(params.get("warehouseCode"))){
            queryWrapper.like("warehouse_code",params.get("warehouseCode"));
        }
        if(!StrUtil.isBlankIfStr(params.get("outState"))){
            queryWrapper.like("out_state",params.get("outState"));
        }*/
        queryWrapper.orderByAsc("id");
        return queryWrapper;
    }
}
